package com.seckill.page.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.heima.minio.MinIOTemplate;
import com.seckill.goods.pojo.Sku;
import com.seckill.page.service.PageService;
import com.seckill.util.Result;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;

@Service
@Slf4j
public class PageServiceImpl implements PageService {
    @Autowired
    private MinIOTemplate minIOTemplate;

    @Autowired
    private Configuration configuration;

    @Override
    public Result html(String id) {

        return null;
    }

    /**
     * 单个生成
     * @param sku
     * @return
     */
    @Override
    public Sku html(Sku sku) {
        if (sku == null) {
            throw new RuntimeException("数据无效!");
        }

        try {
            Template template = configuration.getTemplate("item.ftl");
            Map<String, Object> dataModel = new HashMap<>(1);
            dataModel.put("sku", sku);
            StringWriter stringWriter = new StringWriter();
            template.process(dataModel,stringWriter);
            String html = stringWriter.getBuffer().toString();
            String htmlUrl = minIOTemplate.uploadHtmlFile("html", sku.getId() + ".html", new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8)));
            sku.setHtmlUrl(htmlUrl);
            log.info( "名为:" + Thread.currentThread().getName() + "生成的静态化页面为: " + htmlUrl);
        } catch (Exception e){
            throw new RuntimeException("静态化商品失败, 商品id为: " +sku.getId() + ", 原因为: " + e.getMessage());
        }

        return sku;
    }

    /**
     * 批量生成
     * @param skus
     * @return
     */
    @Override
    public List<Sku> batchHtml(List<Sku> skus) throws InterruptedException {
        if (CollUtil.isEmpty(skus)) {
            return skus;
        }
        List<Sku> skuList = new ArrayList<>();
        CountDownLatch countDownLatch = new CountDownLatch(skus.size());
        for (Sku sku : skus) {
            CompletableFuture
                    .supplyAsync(() ->
                    {
                        try {
                            return html(sku);
                        } catch (Exception e) {
                            throw new RuntimeException(e.getMessage());
                        } finally {
                            countDownLatch.countDown();
                        }
                    })
                    .whenCompleteAsync((result, ex) -> {
                        if (ex == null) {
                            skuList.add(sku);
                        }
                        //countDownLatch.countDown();
                    });
        }
        countDownLatch.await();
        return skus;
    }
}
